package com.bai.localshop.service.impl;

import cn.hutool.core.bean.BeanException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.bai.localshop.exception.BaseException;
import com.bai.localshop.mapper.UserRoleMapper;
import com.bai.localshop.pojo.dto.RolePageDTO;
import com.bai.localshop.pojo.dto.RoleSaveDTO;
import com.bai.localshop.pojo.dto.RoleUpdateDTO;
import com.bai.localshop.pojo.dto.RoleUpdateStatusDTO;
import com.bai.localshop.pojo.entity.ProductCategory;
import com.bai.localshop.pojo.entity.UserRole;
import com.bai.localshop.pojo.vo.RoleOptionVO;
import com.bai.localshop.pojo.vo.RolePageVO;
import com.bai.localshop.pojo.vo.RoleVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bai.localshop.mapper.RoleMapper;
import com.bai.localshop.pojo.entity.Role;
import com.bai.localshop.service.RoleService;
import jodd.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.bai.localshop.constant.SystemConstants.ROLE_ADMIN;

/**
 * 角色服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    private final RoleMapper roleMapper;
    private final UserRoleMapper userRoleMapper;

    /**
     * 获取角色列表
     */
    @Override
    public List<RoleOptionVO> listRole() {
        LambdaQueryWrapper<Role> queryWrapper = Wrappers.lambdaQuery(Role.class)
                .eq(Role::getStatus, 1);
        List<Role> roleList = baseMapper.selectList(queryWrapper);
        return BeanUtil.copyToList(roleList, RoleOptionVO.class);
    }

    /**
     * 分页查询角色
     */
    @Override
    public IPage<RolePageVO> pageQuery(RolePageDTO requestParam) {
        //设置默认分页查询参数
        int page = requestParam.getPage() != null ? requestParam.getPage() : 1;
        int pageSize = requestParam.getPageSize() != null ? requestParam.getPageSize() : 10;
        // 创建分页对象
        Page<Role> pageQuery = new Page<>(page, pageSize);
        // 构建查询条件
        LambdaQueryWrapper<Role> queryWrapper = Wrappers.lambdaQuery(Role.class);
        // 执行分页查询
        IPage<Role> rolePage = roleMapper.selectPage(pageQuery, queryWrapper);
        // 转换为VO对象并返回
        return rolePage.convert(role -> BeanUtil.toBean(role, RolePageVO.class));
    }

    /**
     * 查询所有角色
     */
    @Override
    public Page<Role> getAllRoles() {
        Page<Role> pageQuery = new Page<>(1, 1000); // 获取所有角色，假设不超过1000个
        return roleMapper.selectPage(pageQuery, null);
    }

    /**
     * 根据ID查询角色
     */
    @Override
    public RoleVO getById(Long id) {
        return BeanUtil.toBean(baseMapper.selectById(id), RoleVO.class);
    }

    /**
     * 修改角色
     */
    @Override
    public void update(RoleUpdateDTO requestParam) {
        LambdaQueryWrapper<Role> queryWrapper = Wrappers.lambdaQuery(Role.class)
                .and(wrapper -> wrapper
                        .eq(Role::getRoleName, requestParam.getRoleName())
                        .or()
                        .eq(Role::getRoleCode, requestParam.getRoleCode())
                )
                .ne(Role::getId, requestParam.getId()); // 排除当前角色;
        Role role = baseMapper.selectOne(queryWrapper);
        if (role != null) {
            throw new BaseException("角色名称或角色编码已存在，请重新输入");
        }
        //todo  修改角色名称后，也要修改userRole表以及user表
        //如果更新了角色名称，
        LambdaUpdateWrapper<Role> updateWrapper = Wrappers.lambdaUpdate(Role.class)
                .set(Role::getRoleName, requestParam.getRoleName())
                .set(Role::getDescription, requestParam.getDescription())
                .set(Role::getStatus, requestParam.getStatus())
                .set(Role::getRoleCode,requestParam.getRoleCode())
                .eq(Role::getId, requestParam.getId());
        baseMapper.update(updateWrapper);
    }

    /**
     * 删除角色
     */
    @Override
    public void deleteById(Long id) {
        Role role = roleMapper.selectById(id);
        if (role == null) {
            throw new BaseException("角色不存在");
        }
        if (ROLE_ADMIN.equals(role.getRoleCode())) {
            throw new BaseException("系统默认角色不能删除");
        }
        LambdaQueryWrapper<UserRole> queryWrapper = Wrappers.lambdaQuery(UserRole.class)
                .eq(UserRole::getRoleId, id);
        if (userRoleMapper.selectCount(queryWrapper) > 0) {
            throw new BaseException("角色分类下有用户，不能删除");
        }
        roleMapper.deleteById(id);
    }

    /**
     * 更新角色状态
     */
    @Override
    public void updateStatus(RoleUpdateStatusDTO requestParam) {
        Integer status = requestParam.getStatus();
        Long id = requestParam.getId();

        // 校验状态值
        if (status != 0 && status != 1) {
            throw new BaseException("状态值不合法");
        }

        Role role = baseMapper.selectById(id);
        if (role == null) {
            throw new BaseException("角色不存在");
        }

        if (status == 0) {
            LambdaQueryWrapper<UserRole> queryWrapper = Wrappers.lambdaQuery(UserRole.class)
                    .eq(UserRole::getRoleId, id);

            if (userRoleMapper.selectCount(queryWrapper) > 0) {
                throw new BaseException("角色下有关联用户，不能禁用");
            }

            if (ROLE_ADMIN.equals(role.getRoleCode())) {
                throw new BaseException("系统默认角色不能禁用");
            }
        }

        // 更新状态
        Role updateRole = new Role();
        updateRole.setId(id);
        updateRole.setStatus(status);
        baseMapper.updateById(updateRole);
    }

    /**
     * 新增角色
     */
    @Override
    public void saveRole(RoleSaveDTO requestParam) {
        //判断角色名是否存在
        LambdaQueryWrapper<Role> queryWrapper = Wrappers.lambdaQuery(Role.class)
                .eq(Role::getRoleName, requestParam.getRoleName())
                .eq(Role::getRoleCode, requestParam.getRoleCode());
        if (baseMapper.selectCount(queryWrapper) > 0) {
            throw new BaseException("角色名称或角色编码已存在，请重新输入");
        }
        baseMapper.insert(BeanUtil.toBean(requestParam, Role.class));
    }
}